home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher+1.2b4 / object / DAarray.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-26  |  4.9 KB  |  266 lines

  1. /********************************************************************
  2.  * lindner
  3.  * 3.2
  4.  * 1993/03/26 19:52:10
  5.  * /home/mudhoney/GopherSrc/CVS/gopher+/object/DAarray.c,v
  6.  * Exp
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: DAarray.c
  14.  * Dynamic Array Implementation
  15.  *********************************************************************
  16.  * Revision History:
  17.  * DAarray.c,v
  18.  * Revision 3.2  1993/03/26  19:52:10  lindner
  19.  * Fixed off by one prob in DApop
  20.  *
  21.  * Revision 3.1.1.1  1993/02/11  18:03:01  lindner
  22.  * Gopher+1.2beta release
  23.  *
  24.  * Revision 1.3  1992/12/21  21:14:57  lindner
  25.  * Fixed bug in DAcpy, initfn wasn't being copied right.
  26.  *
  27.  * Revision 1.2  1992/12/21  20:04:04  lindner
  28.  * Added DAcpy()
  29.  *
  30.  * Revision 1.1  1992/12/10  23:27:52  lindner
  31.  * gopher 1.1 release
  32.  *
  33.  *
  34.  *********************************************************************/
  35.  
  36.  
  37. #include "DAarray.h"
  38.  
  39. #include "Malloc.h"
  40.  
  41. /*
  42.  * Create a new dynamic array
  43.  *
  44.  * size      -- the initial number of elements
  45.  * newfn     -- creates new object
  46.  * initfn    -- initializes the object
  47.  * destroyfn -- performs clean up and frees objs memory
  48.  * copyfn    -- copys one obj to the other, like strcpy
  49.  */
  50.  
  51. DynArray *
  52. DAnew(size, newfn, initfn, destroyfn, copyfn)
  53.   int size;
  54.   char * (*newfn)();
  55.   void   (*initfn)();
  56.   void   (*destroyfn)();
  57.   char * (*copyfn)();
  58. {
  59.      DynArray *temp;
  60.      int i;
  61.      
  62.      temp = (DynArray*) malloc(sizeof(DynArray));
  63.      temp->objects = (char **) malloc(size * sizeof(char *));
  64.      temp->newfn     = newfn;
  65.      temp->initfn    = initfn;
  66.      temp->destroyfn = destroyfn;
  67.      temp->copyfn    = copyfn;
  68.      temp->Top       = 0;
  69.  
  70.      if (copyfn == NULL)
  71.       /** Can't work without this!!! ***/
  72.       perror("Egad, no copy function in DAnew()!!");
  73.  
  74.      if (newfn != NULL)
  75.       for (i = 0; i < size; i++)
  76.            temp->objects[i] = (char *) newfn();
  77.  
  78.      temp->maxsize = size;
  79.      return(temp);
  80. }
  81.  
  82.  
  83. void DAdestroy(da)
  84.   DynArray *da;
  85. {
  86.      int i;
  87.      
  88.      if (da->destroyfn != NULL)
  89.       for (i = 0; i< da->maxsize; i++)
  90.            da->destroyfn(da->objects[i]);
  91.  
  92.      free(da->objects);
  93.      free(da);
  94. }
  95.  
  96.  
  97. void
  98. DAinit(da)
  99.   DynArray *da;
  100. {
  101.      int i;
  102.      
  103.      if (da->initfn!=NULL)
  104.       for (i=0; i<da->maxsize; i++)
  105.            da->initfn(DAgetEntry(da, i));
  106.  
  107.      DAsetTop(da, 0);
  108. }
  109.  
  110. void
  111. DAgrow(da, size)
  112.   DynArray *da;
  113.   int size;
  114. {
  115.      char **temp;
  116.      int i;
  117.  
  118.      if (size < da->maxsize)
  119.       return; /** Size is smaller than requested **/
  120.  
  121.      temp = (char **) realloc(da->objects, size*sizeof(char*));
  122.  
  123.      if (temp == NULL)
  124.       perror("Out of memory!!!\n"), exit(-1);
  125.  
  126.      if (temp != da->objects) {
  127.       da->objects = temp;
  128.      }
  129.  
  130.      /** Initialize the new objects.  **/
  131.  
  132.      for (i= da->maxsize; i< size; i++)
  133.       da->objects[i] = da->newfn();
  134.      
  135.      da->maxsize = size;
  136.      return;
  137. }
  138.  
  139. /*
  140.  * Tacks an item on the end of the array, grows it if necessary..
  141.  */
  142.  
  143. void
  144. DApush(da, obj)
  145.   DynArray *da;
  146.   char *obj;
  147. {
  148.      int top;
  149.  
  150.      top = DAgetTop(da);
  151.      
  152.      if (top == da->maxsize)
  153.       DAgrow(da, da->maxsize*2);
  154.  
  155.      da->copyfn(DAgetEntry(da, top), obj);
  156.  
  157.      DAsetTop(da, top+1);                /* update end of list */
  158. }
  159.  
  160. char *
  161. DApop(da)
  162.   DynArray *da;
  163. {
  164.      int top;
  165.      char *newobj;
  166.      
  167.      top = DAgetTop(da);
  168.  
  169.      if (top == 0)
  170.       return(NULL);  /** Nothing to pop! **/
  171.  
  172.      newobj = da->newfn();
  173.      da->initfn(newobj);
  174.      
  175.      top--;
  176.      da->copyfn(newobj, DAgetEntry(da, top));
  177.  
  178.      DAsetTop(da, top);
  179.  
  180.      return(newobj);
  181. }
  182.  
  183. void 
  184. DAsort(da, sortfn)
  185.   DynArray *da;
  186.   int (*sortfn)();
  187. {
  188.      char *moo;
  189.  
  190.      moo = (char *) &((da->objects)[0]);
  191.      
  192.      qsort(moo, da->Top,
  193.        sizeof(char *), sortfn);
  194. }
  195.  
  196.  
  197. void
  198. DAcpy(dest, orig)
  199.   DynArray *dest;
  200.   DynArray *orig;
  201. {
  202.      int i;
  203.  
  204.      DAsetTop(dest, 0);
  205.      dest->newfn = orig->newfn;
  206.      dest->initfn = orig->initfn;
  207.      dest->destroyfn = orig->destroyfn;
  208.      dest->copyfn = dest->copyfn;
  209.  
  210.      for (i=0; i<DAgetTop(orig); i++) {
  211.       DApush(dest, DAgetEntry(orig,i));
  212.      }
  213. }
  214. #ifdef DA_TEST
  215.  
  216. #include <stdio.h>
  217. #include <string.h>
  218.  
  219. char *makespace()
  220. {
  221.      return(malloc(256));
  222. }
  223.  
  224. int DEBUG = 1;
  225.  
  226. int
  227. moostrcmp(s1, s2)
  228.   char **s1, **s2;
  229. {
  230.      printf("Comparing %s, %s\n", *s1,*s2);
  231.      return(strcmp(*s1,*s2));
  232. }
  233.  
  234. main()
  235. {
  236.      DynArray *test;
  237.      int i;
  238.      char tempstr[100];
  239.  
  240.      printf("Testing Dynamic Arrays...\n\n");
  241.      
  242.      test = DAnew(5, makespace, NULL, NULL, strcpy);
  243.  
  244.      DApush(test, "ziggy\n");
  245.      DApush(test, "iggy\n");
  246.      
  247.      for (i= 10; i >0; i--) {
  248.       sprintf(tempstr, "Moocow #%d\n", i);
  249.       printf(tempstr);
  250.       DApush(test, tempstr);
  251.      }
  252.  
  253.      for (i=0; i< 10; i++) {
  254.       printf(DAgetEntry(test, i));
  255.      }
  256.  
  257.      DAsort(test, moostrcmp);
  258.  
  259.      for (i=0; i< 10; i++) {
  260.       printf(DAgetEntry(test, i));
  261.      }
  262.  
  263. }
  264.  
  265. #endif
  266.